# -*- coding: utf-8 -*-
"""
Created on Tue Oct  8 18:20:10 2019

@author: minuks3
"""
import mysql.connector
import numpy as np
from mysql.connector import Error
import perform_sim
import convertSvals
import socket
import datetime
import monitor_client
import database_comm as database
import time

WIDTH_NUM_DECIMALS = 4 # The number of decimals to round the width of the dogbone to.

ENABLE_MONITOR = False

MAX_TRIES = 3

def runSims(length, widths, traces):
    if ENABLE_MONITOR:
        monitor_client.send_start_signal(monitorServer)
    
    tries = 0
        
    for width in widths:
        for trace in traces:   
            try:
                # Check to see if this sim has already been performed
                if(database.simulationExists(trace, length, width)):
                    print("Simulation skipped, results already exist for trace = "+trace+" and width = "+str(round(width, WIDTH_NUM_DECIMALS))+"mm.")
                    continue

                # Print simulation values
                print("Simulation Starting")
                print("INPUTS")
                print("  Trace Position: "+trace)
                print("   Dogbone Width: "+str(width)+"mm")
                
                while(tries < MAX_TRIES):
                    # Run the simulation and retrive a 2x2 S matrix
                    startTime = time.time()
                    result = perform_sim.runsim(trace,width,length,delta_s)
                    simTime = time.time() - startTime
                                    
                    # If the simulation performed properly
                    if(len(result)>0):
                        # Convert the S matrix from the simulation into an impedance
                        z_im = convertSvals.convert_svals(result[0]["sMat"],trace)  # Convert S mat to im(Z)
                        
                        # Upload results
                        database.uploadResults(width, length, z_im, trace, result[0]["converged"], result[0]["delta_s"], simTime)                # Upload results to database
                        
                        # Print S Matrix
                        print("OUTPUTS")
                        print("  S Matrix:")
                        print(result[0]["sMat"])
                        print("     im(z): "+str(z_im)+"j")
                        
                        if ENABLE_MONITOR:
                            monitor_client.send_confirmation(monitorServer, width, trace, z_im)    # Inform monitor server
                            
                        break # break out of retry loop
                    else:
                        tries = tries + 1
                        if(tries == MAX_TRIES):
                            print("Max Tries reached, aborting")
                            return
                        
                        print("Simulation Failed, trying again in 30 seconds...")
                        time.sleep(30)      # wait 30 seconds before trying again
                            
                    result=[]
                
            except Error as e:
                print("Error communicating with the MySQL server", e)
    if ENABLE_MONITOR:
        monitor_client.send_stop_signal(monitorServer)
                
            #print()
                


try:
    # Connect to the mySQL server.
    database.connect()
    
    # Connect to monitoring server
    if ENABLE_MONITOR:
        monitorServer = monitor_client.connect_to_server()
    
    # Run the simulations
    runSims(4.1, np.arange(.5,5.0,.01), ["top","mid","bot"])
    
    # Disconnect from monitoring server
    if ENABLE_MONITOR:
        monitor_client.disconnect(monitorServer)
    
    #disconnect from database
    database.disconnect()
        
except Error as e:
    print("Error Connecting to Database", e)